/*
 * Copyright 2011 myTDev.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.mytdev.commons.net;

import com.mytdev.commons.server.ServerEngine;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.concurrent.TimeoutException;

/**
 * A simple ServerEngine<Socket> using a ServerSocket.
 * 
 * @author Yann D'Isanto
 */
public class ServerSocketEngine implements ServerEngine<Socket> {

    private ServerSocket server;

    /**
     * Creates a ServerSocketEngine, bound to the specified port. 
     * @param port the port number, or 0 to use any free port.
     * @throws IOException if an I/O error occurs when opening the socket.
     */
    public ServerSocketEngine(int port) throws IOException {
        this(new ServerSocket(port));
    }

    /**
     * Creates a ServerSocketEngine and binds it to the specified local port 
     * number, with the specified backlog.
     * @param port the port number, or 0 to use any free port.
     * @param backlog the maximum length of the queue.
     * @throws IOException if an I/O error occurs when opening the socket.
     */
    public ServerSocketEngine(int port, int backlog) throws IOException {
        this(new ServerSocket(port, backlog));
    }

    /**
     * Create a ServerSocketEngine with the specified port, listen backlog, and local IP address to bind to.
     * @param port the local TCP port.
     * @param backlog the listen backlog.
     * @param bindAddress the local InetAddress the server will bind to.
     * @throws IOException if an I/O error occurs when opening the socket.
     */
    public ServerSocketEngine(int port, int backlog, InetAddress bindAddress) throws IOException {
        this(new ServerSocket(port, backlog, bindAddress));
    }

    /**
     * Create a ServerSocketEngine with the specified server socket.
     * @param server the server socket
     */
    public ServerSocketEngine(ServerSocket server) {
        if(server == null) {
            throw new NullPointerException("server socket is null");
        }
        this.server = server;
    }

    @Override
    public Socket listen() throws IOException, TimeoutException {
        Socket socket = null;
        try {
            socket = server.accept();
        } catch (SocketTimeoutException ex) {
            throw new TimeoutException(ex.getMessage());
        }
        return socket;
    }

    @Override
    public int getTimeout() throws IOException {
        return server.getSoTimeout();
    }

    @Override
    public void setTimeout(int timeout) throws IOException {
        server.setSoTimeout(timeout);
    }
}
